package maple.widgets;

import java.awt.Container;
import java.awt.GridLayout;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.Date;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JComboBox;
import javax.swing.JTextField;

import com.phidgets.event.DetachEvent;
import com.phidgets.event.DetachListener;
import com.phidgets.InterfaceKitPhidget;
import com.phidgets.PhidgetException;

import maple.util.Sensor;
import maple.util.Timestamp;

class Window extends JFrame
{
	private JComboBox locations;
	private JComboBox[] types;

	public Window( final String device, final int serial, final int size )
	{
		types = new JComboBox[ size ];

		setTitle( "MAPLE Logger" );

		Container container = getContentPane();
		container.setLayout( new GridLayout( 4, 2, 5, 5 ) );

		JLabel label = null; 

		container.add( label = new JLabel( "Gateway" ) );
		label.setHorizontalAlignment( JLabel.CENTER );
		JTextField gateway = new JTextField( device + "_" + serial );
		gateway.setEditable( false );
		container.add( gateway );

		container.add( label = new JLabel( "Location" ) );
		label.setHorizontalAlignment( JLabel.CENTER );
		String[] room = { "",
						  "R101", "R102", "R103", "R104", "R105",
						  "R106", "R107", "R108", "R110", "R111", 
						  "R201", "R202", "R203", "R204", "R205",
						  "R210", "R215", "R217", "R219",
						  "R309", "R310", "R318", "R319", "R324",
						  "R336", "R340",
						  "R409", "R439", "R440", "R446",
						  "R509", "R510", "R519", "R524", "R539",
						  "R540", "R542", "R544", "R546"
						};
		container.add( locations = new JComboBox( room ) );

		types[ 0 ] = new JComboBox();
		types[ 1 ]  = new JComboBox();
		types[ 0 ].addItem( "" );
		types[ 1 ].addItem( "" );
		for( Sensor.Type type : Sensor.Type.values() )
		{
			if( type != Sensor.Type.MASTER && type != Sensor.Type.GATEWAY
					&& type != Sensor.Type.III_ACTIVEPOWER 
					&& type != Sensor.Type.III_POWERFACTOR )
			{
				types[ 0 ].addItem( type.toString() );
				types[ 1 ].addItem( type.toString() );
			}
		}
		types[ 0 ].setSelectedIndex( 1 );
		types[ 0 ].setEnabled( false );
		types[ 1 ].setSelectedIndex( 5 );
		types[ 1 ].setEnabled( false );
		container.add( label = new JLabel( "Port A.0" ) );
		label.setHorizontalAlignment( JLabel.CENTER );
		container.add( types[ 0 ] );
		container.add( label = new JLabel( "Port A.1" ) );
		label.setHorizontalAlignment( JLabel.CENTER );
		container.add( types[ 1 ] );
	}

	public String getDeviceLocation()
	{
		return locations.getSelectedItem().toString();
	}

	public String getDeviceType( final int index )
	{
		return types[ index ].getSelectedItem().toString();
	}
}

public class Logger extends Object
{
	static final int INTERVAL = 60000;
	static final String DEVICE = "PhidgetInterfaceKit";
	static boolean _available = true;

	static Window window;

	public static void main( String[] args ) throws ClassNotFoundException, PhidgetException
	{
		InterfaceKitPhidget handler = new InterfaceKitPhidget();
		handler.openAny();
		handler.waitForAttachment( 5000 );

		int exception = 0;

		if( handler.isAttached() )
		{
			int serial = handler.getSerialNumber();
			int size = handler.getSensorCount();

			window = new Window( DEVICE, serial, size );
			window.setBounds( 50, 100, 400, 160 );
			window.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
			window.setVisible( true );

			handler.setRatiometric( true );
			handler.addDetachListener( new DetachListener()
			{
				public void detached( DetachEvent e )
				{
					_available = false;
				}
			} );

			// connect to database
			Class.forName( "com.mysql.jdbc.Driver" );

			while( exception < 10 )
			{
				try
				{
					exception = 0;

					Connection database = DriverManager.getConnection( "jdbc:mysql://gardenia.csie.ntu.edu.tw:3306/maple", "maple", "dpsSjbMeKfXHaXzA" );
					PreparedStatement statement = database.prepareStatement( "INSERT INTO observations ( sensed_time, gateway, port, sensor, location, value, received_time ) values( ?, ?, ?, ?, ?, ?, ? )" );
					while( _available )
					{
						long current = System.currentTimeMillis();
						Long timestamp = Long.parseLong( Timestamp.Default.format( new Date( current ) ) ); 
						for( int i = 0; i < size; ++i )
						{
							String type = window.getDeviceType( i );
							String location = window.getDeviceLocation();
							if( !type.equals( "" ) && !location.equals( "" ) )
							{
								String value = Sensor.toString( type, "" + handler.getSensorValue( i ) );
								statement.setLong( 1, timestamp ); 
								statement.setString( 2, DEVICE + "_" + serial ); 
								statement.setString( 3, "A." + i ); 
								statement.setString( 4, type ); 
								statement.setString( 5, location ); 
								statement.setDouble( 6, Double.parseDouble( value ) ); 
								statement.setLong( 7, timestamp ); 
								statement.setQueryTimeout( 1 );
								statement.execute();
								statement.clearParameters();
								System.out.println( timestamp + " " + value );
							}
						}

						while( System.currentTimeMillis() - current < INTERVAL )
						{
						}
					}

					database.close();
				}
				catch( SQLException e )
				{
					++exception;
					e.printStackTrace();
				}
			}
			
			handler.close();
			window.dispose();
		}
	}
}
